package JavaStudy.ReentrantReadWriteLockDemo;

import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @author welsir
 * @version 1.0
 * @description: TODO
 * @date 2022/11/1 21:30
 */
@Slf4j
public class CacheDemo {

    static volatile Boolean flag = false;
    static ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    static LRUCache<Integer, String> cache = null;
    static Random random = new Random();

    static void write(Integer key,String value) throws InterruptedException {
        if (!flag) {
            lock.writeLock().lock();
            if (!flag) {
                Thread.sleep(1000);
                cache.put(key,value);
                log.debug(cache.get(key));
                flag = true;
                if(cache.size()==4){
                    log.debug("内存已满，删除队尾key...");
                    log.debug("删除后的Cache:"+cache);
                }
            }else {
                log.debug("缓存正在被写入!");
            }
            lock.writeLock().unlock();
            flag=false;
        }else {
            log.debug("缓存正在被写入!");
        }
    }

    static Boolean read() throws InterruptedException {
        if(!flag){
            Thread.sleep(1000);
            lock.readLock().lock();
            flag = true;
            log.debug("缓存队列:"+String.valueOf(cache));
            lock.readLock().unlock();
            flag = false;
            return true;
        }
        return false;
    }

    public static void main(String[] args) throws InterruptedException {
        cache = new LRUCache<>(5);
        for(int i=0;i<10;i++){
            int finalI = i;
            Runnable r1 = new Runnable() {
                @Override
                public void run() {
                    try {
                        log.debug("正在尝试写入缓存...");
                        write(finalI, finalI + "加入缓存");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            };

            Runnable r2 = new Runnable() {
                @Override
                public void run() {
                    try {
                        log.debug("正在尝试读取缓存内容");
                        Boolean read = read();
                        if (read) {
                            log.debug("读取缓存成功!");
                        } else {
                            log.debug("读取缓存失败!");
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            };
            Runnable r3 = new Runnable() {
                @Override
                public void run() {
                    try {
                        log.debug("正在尝试读取缓存内容");
                        Boolean read = read();
                        if (read) {
                            log.debug("读取缓存成功!");
                        } else {
                            log.debug("读取缓存失败!");
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            };
            Thread.sleep(random.nextInt(1000));
            r2.run();
            r1.run();
            r3.run();
        }
    }
}
